package com.netease.rtcdemo;

import android.content.Context;
import android.content.res.AssetManager;
import android.net.Uri;
import android.util.Log;

import com.netease.lava.nertc.sdk.stats.NERtcAudioRecvStats;
import com.netease.lava.nertc.sdk.stats.NERtcAudioSendStats;
import com.netease.lava.nertc.sdk.stats.NERtcNetworkQualityInfo;
import com.netease.lava.nertc.sdk.stats.NERtcStats;
import com.netease.lava.nertc.sdk.stats.NERtcStatsObserver;
import com.netease.lava.nertc.sdk.stats.NERtcVideoLayerSendStats;
import com.netease.lava.nertc.sdk.stats.NERtcVideoRecvStats;
import com.netease.lava.nertc.sdk.stats.NERtcVideoSendStats;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

public class StatsHelper implements NERtcStatsObserver {
    // 加载本地库
    static {
        System.loadLibrary("native-lib");
    }

    private static StatsHelper instance;
    private Context mContext;
    multiChatActivity sink;
    boolean enableQuality;
    // 私有构造函数，防止外部实例化
    private StatsHelper() {}

    public static StatsHelper getInstance() {
        if (instance == null) {
            synchronized (StatsHelper.class) {
                if (instance == null) {
                    instance = new StatsHelper();
                }
            }
        }
        return instance;
    }

    public void setSink(multiChatActivity multiChatActivity) {
        sink = multiChatActivity;
    }

    public void setEnableQuality(boolean enableQuality) {
        this.enableQuality = enableQuality;
    }

    public void setContext(Context context) {
        mContext = context.getApplicationContext();
    }

    private ArrayList<Integer> cpu_usage_array = new ArrayList<>();
    private ArrayList<Integer> mem_usage_array = new ArrayList<>();
    private ArrayList<Integer> audio_send_loss_array = new ArrayList<>();
    private ArrayList<Integer> video_send_loss_array = new ArrayList<>();
    private ArrayList<Integer> audio_recv_loss_array = new ArrayList<>();
    private ArrayList<Integer> video_recv_loss_array = new ArrayList<>();
    private ArrayList<Integer> send_bytes_array = new ArrayList<>();
    private ArrayList<Integer> recv_bytes_array = new ArrayList<>();
    private ArrayList<Integer> audio_stuck_array = new ArrayList<>();
    private ArrayList<Integer> video_stuck_array = new ArrayList<>();
    private ArrayList<Integer> audio_jitter_array = new ArrayList<>();
    private ArrayList<Integer> video_jitter_array = new ArrayList<>();


    // 声明本地方法
    public native ArrayList<Integer> downsample(ArrayList<Integer> list, int max_size);
    public native String buildHTML(ArrayList<ArrayList<Integer>> arrayLists, ArrayList<String> arrayTitleLists, ArrayList<String> arrayNameLists, String htmlTemplate);

    public String readHtmlFromAssets() {
        if(mContext == null){
            return "";
        }
        StringBuilder htmlContent = new StringBuilder();
        AssetManager assetManager = mContext.getAssets();
        try {
            // 打开 assets 目录下的 index.html 文件
            InputStream inputStream = assetManager.open("index.html");
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String line;
            // 逐行读取文件内容
            while ((line = bufferedReader.readLine()) != null) {
                htmlContent.append(line);
            }

            // 关闭资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
        } catch (IOException e) {
            // 读取文件出错，打印错误信息并返回空字符串
            e.printStackTrace();
            return "";
        }
        return htmlContent.toString();
    }

    public Uri getBaseUrlForAsset(String resourceName, String resourceType) {
        String fileName = resourceName + "." + resourceType;
        try {
            // 尝试打开文件，检查文件是否存在
            InputStream inputStream = mContext.getAssets().open(fileName);
            inputStream.close();

            // 构建文件所在目录的 Uri
            return Uri.parse("file:///android_asset/");
        } catch (IOException e) {
            // 文件不存在，打印错误信息
            e.printStackTrace();
            return null;
        }
    }

    public String htmlContent(){
        int maxSize = 40;
        ArrayList<ArrayList<Integer>> res = new ArrayList<>();
        ArrayList<String> resTitle = new ArrayList<>();
        ArrayList<String> resName = new ArrayList<>();

        res.add(downsample(cpu_usage_array, maxSize));
        res.add(downsample(mem_usage_array, maxSize));
        res.add(downsample(send_bytes_array, maxSize));
        res.add(downsample(recv_bytes_array, maxSize));
        res.add(downsample(audio_send_loss_array, maxSize));
        res.add( downsample(audio_recv_loss_array, maxSize));
        res.add(downsample(video_send_loss_array, maxSize));
        res.add(downsample(video_recv_loss_array, maxSize));

        resTitle.add("chart_cpu");
        resTitle.add("chart_mem");
        resTitle.add("chart_up_bytes");
        resTitle.add("chart_down_bytes");
        resTitle.add("chart_a_loss");
        resTitle.add("chart_a_d_loss");
        resTitle.add("chart_v_loss");
        resTitle.add("chart_v_d_loss");

        resName.add("CPU 使用百分比");
        resName.add("内存使用百分比");
        resName.add("视频上行发送码率(kbps)");
        resName.add("视频下行接收码率(kbps)");
        resName.add("音频上行丢包百分比");
        resName.add("音频下行丢包百分比");
        resName.add("视频上行丢包百分比");
        resName.add("视频下行丢包百分比");
        String htmlTemplate = readHtmlFromAssets();
        return buildHTML(res,resTitle,resName, htmlTemplate);
    }


    @Override
    public void onRtcStats(NERtcStats stats) {
        cpu_usage_array.add(stats.cpuAppUsage);
        mem_usage_array.add(stats.memoryAppUsageRatio);

        video_send_loss_array.add(stats.txVideoPacketLossRate);
        audio_send_loss_array.add(stats.txAudioPacketLossRate);
        audio_recv_loss_array.add(stats.rxAudioPacketLossRate);
        video_recv_loss_array.add(stats.rxVideoPacketLossRate);
    }

    @Override
    public void onLocalAudioStats(NERtcAudioSendStats stats) {
        if(sink != null && enableQuality){
            sink.onLocalAudioStats(stats);
        }
    }

    @Override
    public void onRemoteAudioStats(NERtcAudioRecvStats[] statsArray) {
        if(sink != null && enableQuality){
            sink.onRemoteAudioStats(statsArray);
        }
    }

    @Override
    public void onLocalVideoStats(NERtcVideoSendStats stats) {
        for (int i = 0;i <stats.videoLayers.size() ;i++) {
            if (stats.videoLayers.get(i).layerType == 1) { // 主流
                send_bytes_array.add(stats.videoLayers.get(i).sendBitrate);
            }
        }
        if(sink != null && enableQuality){
            sink.onLocalVideoStats(stats);
        }
    }

    @Override
    public void onRemoteVideoStats(NERtcVideoRecvStats[] statsArray) {
        int bytes = 0;
        for (int i = 0;i < statsArray.length;i++) {
            for(int j = 0;j < statsArray[i].layers.size();j++){
                if(statsArray[i].layers.get(j).layerType == 1){
                    bytes += statsArray[i].layers.get(j).receivedBitrate;
                }
            }
        }
        recv_bytes_array.add(bytes);
        if(sink != null && enableQuality){
            sink.onRemoteVideoStats(statsArray);
        }
    }

    @Override
    public void onNetworkQuality(NERtcNetworkQualityInfo[] statsArray) {

    }


}
